package eu.telecombretagne.rsm.network;

import java.net.*;
import java.util.concurrent.*;
import java.io.*;

import eu.telecombretagne.rsm.base.event.*;
import eu.telecombretagne.rsm.gui.NameConsts;
import eu.telecombretagne.rsm.gui.frames.DesktopFrame;
import eu.telecombretagne.rsm.network.utils.ServerManager;

public class Network implements Runnable {
	
	private volatile Thread networkThread;
	
	private ServerSocket serverSocket_;
	
	private ArrayBlockingQueue<Event> _vA = new ArrayBlockingQueue<Event> (100);
	private ArrayBlockingQueue<Event> _vB = new ArrayBlockingQueue<Event> (100);

	
	public Network(){
		DesktopFrame.writeLogNetwork(NameConsts.INITIALIZINGTHENETWORK);
		
		try {
			serverSocket_ = ServerManager.getServerSocket();
		} catch (BindException be) {
			DesktopFrame.writeLogError(NameConsts.APPLICATIONHASRUNOUTFROMFREEPORTS);
			System.exit (1);
		}
	}
	
	public Network start(){
		networkThread = new Thread(this);
		networkThread.start();
		
		return this;
	}
	
	public Network stop(){
		networkThread = null;
		return null;
	}
	
	public void run(){
		ThreadStatus emitter = new ThreadStatus();
		ThreadStatus receiver = new ThreadStatus();
		
		Thread thisThread = Thread.currentThread();
		
		while(networkThread == thisThread){			
			try {
				Socket s = serverSocket_.accept();

				ObjectInputStream ois = new ObjectInputStream (s.getInputStream ());
				String message = (String) ois.readObject();
			//	System.out.println ("Received ..." + message);

				if (!(message.equals("READER_EMITTER") | message.equals("READER_RECEIVER") | message.equals("WRITER_EMITTER") | message.equals("WRITER_RECEIVER"))) {
					DesktopFrame.writeLogNetwork(NameConsts.CONNECTIONREFUSED);
					ois.close();
					s.close ();
				}

				if (message.equals("READER_EMITTER") && (emitter.writerisOn == false)) {
					synchronized (emitter) {
					//	_vA.clear();
						Thread t = new WriterThread (s, _vA, emitter);
						emitter.t = t;
						emitter.writerisOn = true;
						emitter.t.start();
					}
				}
				if (message.equals("WRITER_RECEIVER") && (receiver.readerisOn == false)){
					synchronized (receiver) {
				//		_vA.clear();
						Thread t = new ReaderThread (_vA, receiver, ois);
						receiver.t = t;
						receiver.readerisOn = true;
						receiver.t.start();
					}
				}	
				if (message.equals("READER_RECEIVER") && (receiver.writerisOn == false)) {
					synchronized (receiver) {
					//	_vB.clear();
						Thread t = new WriterThread (s, _vB, receiver);
						receiver.t = t;
						receiver.writerisOn = true;
						receiver.t.start();
					}	
				}
				if (message.equals("WRITER_EMITTER") && (emitter.readerisOn == false)) {
					synchronized (emitter) {
				//		_vB.clear();
						Thread t = new ReaderThread (_vB, emitter, ois);
						emitter.t = t;
						emitter.readerisOn = true;
						emitter.t.start();
					}
				}		
			}
			catch (IOException ioe) {
				DesktopFrame.writeLogError(this.getClass().getSimpleName() + ": " + ioe);
				System.exit(1);
			}
			catch (ClassNotFoundException cnfe) {
				DesktopFrame.writeLogError(this.getClass().getSimpleName() + ": " + cnfe);
				System.exit (1);
			}
		}
	}
}